#include "danstm32.h"
#include "ui_danstm32.h"

DanStm32::DanStm32(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::DanStm32)
{
    ui->setupUi(this);
    timer = new QTimer(this);

    // 提前刷新显式控件
    timeoutSlot();

    timer->setInterval(1000);   // 设置时间间隔1秒钟
    timer->setSingleShot(false);    // 为周期循环

    // 连接信号槽要在启动定时器之前连接
    connect(timer,SIGNAL(timeout()),this,SLOT(timeoutSlot()));
    // 启动定时器
    timer->start();
    connect(ui->pushButtonHot,SIGNAL(clicked()),this,SLOT(Controls()));  //加热片
    connect(ui->pushButtonCold,SIGNAL(clicked()),this,SLOT(Controls()));  //制冷片
    connect(ui->pushButtonBuzzer,SIGNAL(clicked()),this,SLOT(Controls()));  //蜂鸣器
    connect(ui->pushButtonFan,SIGNAL(clicked()),this,SLOT(Controls()));  //风扇

    //火焰报警模拟：假设按下加热片按钮时触发报警，后期能拿到报警信号后可更改
    connect(ui->pushButtonHot,SIGNAL(clicked()),this,SLOT(alarm()));    //火焰报警

    //动图
    // 建电影类对象
    movie = new QMovie(":/new/prefix1/fengji.gif");
    // 给QLabel设置电影
    ui->labelFan->setMovie(movie);
    // 播放电影
    movie->start();
    movie->stop();

    //动态曲线部分
    setupRealtimeDataDemo(ui->customPlot);
    ui->customPlot->replot();

    ui->checkBox_Temperature->setChecked(true);   //温度
    ui->checkBox_Humidness->setChecked(true);     //湿度
}

DanStm32::~DanStm32()//析构函数
{
    // 如果正在运行，则先关闭
    if(timer->isActive())
    {
        timer->stop();
    }
    delete timer;
    delete movie;   //风扇电影对象回收
    delete ui;
}

void DanStm32::timeoutSlot()//显示时间
{
    // 获取当前系统时间，转换为：时:分:秒
    QString str = QDateTime::currentDateTime().toString("hh:mm:ss");
    ui->lcdNumberTim->display(str);
}

void DanStm32::Controls()//开关控制槽函数
{
    if(sender() == ui->pushButtonHot)   //加热片
    {
        if(QString::number(jiarepian.toInt())=="0")//打开
        {
            // 创建JSON对象
            QJsonObject jsonObject;
            // 添加控制指令类型
            jsonObject["type"] = QJsonValue(2);
            // 创建数据子对象
            QJsonObject dataObject;
            // 添加数据点唯一标识和数据点键值
            dataObject["key"] = QJsonValue(307);
            dataObject["val"] = QJsonValue("1");
            // 将数据子对象添加到主对象
            jsonObject["data"] = dataObject;
            // 创建QJsonDocument并添加JSON对象
            QJsonDocument jsonDoc(jsonObject);
            // 将JSON文档序列化为字符串
            QString jsonString = jsonDoc.toJson(QJsonDocument::Compact);
            // 创建一个QMQTT::Message对象
            QMQTT::Message message;
            message.setTopic("/app/data/down"); // 设置发布的主题
            message.setPayload(jsonString.toUtf8()); // 设置消息内容，注意转换
            message.setQos(1); // 设置服务质量等级
            // 使用MqttHandler实例发布消息
            quint16 messageId = GlobalVal::mqtt->publish(message);
            qDebug() << "Message published with ID" << messageId;
            ui->pushButtonHot->setStyleSheet("QPushButton { background-color: red; }");
        }
        if(QString::number(jiarepian.toInt())=="1")//关闭
        {
            // 创建JSON对象
            QJsonObject jsonObject;
            // 添加控制指令类型
            jsonObject["type"] = QJsonValue(2);
            // 创建数据子对象
            QJsonObject dataObject;
            // 添加数据点唯一标识和数据点键值
            dataObject["key"] = QJsonValue(307);
            dataObject["val"] = QJsonValue("0");
            // 将数据子对象添加到主对象
            jsonObject["data"] = dataObject;
            // 创建QJsonDocument并添加JSON对象
            QJsonDocument jsonDoc(jsonObject);
            // 将JSON文档序列化为字符串
            QString jsonString = jsonDoc.toJson(QJsonDocument::Compact);
            // 创建一个QMQTT::Message对象
            QMQTT::Message message;
            message.setTopic("/app/data/down"); // 设置发布的主题
            message.setPayload(jsonString.toUtf8()); // 设置消息内容，注意转换
            message.setQos(1); // 设置服务质量等级
            // 使用MqttHandler实例发布消息
            quint16 messageId = GlobalVal::mqtt->publish(message);
            qDebug() << "Message published with ID" << messageId;
            ui->pushButtonHot->setStyleSheet("QPushButton { background-color: transparent; }");
        }
    }
    if(sender() == ui->pushButtonCold)  //制冷片
    {
        if(QString::number(zhilengpian.toInt())=="0")//打开
        {
            // 创建JSON对象
            QJsonObject jsonObject;
            // 添加控制指令类型
            jsonObject["type"] = QJsonValue(2);
            // 创建数据子对象
            QJsonObject dataObject;
            // 添加数据点唯一标识和数据点键值
            dataObject["key"] = QJsonValue(308);
            dataObject["val"] = QJsonValue("1");
            // 将数据子对象添加到主对象
            jsonObject["data"] = dataObject;
            // 创建QJsonDocument并添加JSON对象
            QJsonDocument jsonDoc(jsonObject);
            // 将JSON文档序列化为字符串
            QString jsonString = jsonDoc.toJson(QJsonDocument::Compact);
            // 创建一个QMQTT::Message对象
            QMQTT::Message message;
            message.setTopic("/app/data/down"); // 设置发布的主题
            message.setPayload(jsonString.toUtf8()); // 设置消息内容，注意转换
            message.setQos(1); // 设置服务质量等级
            // 使用MqttHandler实例发布消息
            quint16 messageId = GlobalVal::mqtt->publish(message);
            qDebug() << "Message published with ID" << messageId;
            ui->pushButtonCold->setStyleSheet("QPushButton { background-color: blue ; }");
        }
        if(QString::number(zhilengpian.toInt())=="1")//关闭
        {
            // 创建JSON对象
            QJsonObject jsonObject;
            // 添加控制指令类型
            jsonObject["type"] = QJsonValue(2);
            // 创建数据子对象
            QJsonObject dataObject;
            // 添加数据点唯一标识和数据点键值
            dataObject["key"] = QJsonValue(308);
            dataObject["val"] = QJsonValue("0");
            // 将数据子对象添加到主对象
            jsonObject["data"] = dataObject;
            // 创建QJsonDocument并添加JSON对象
            QJsonDocument jsonDoc(jsonObject);
            // 将JSON文档序列化为字符串
            QString jsonString = jsonDoc.toJson(QJsonDocument::Compact);
            // 创建一个QMQTT::Message对象
            QMQTT::Message message;
            message.setTopic("/app/data/down"); // 设置发布的主题
            message.setPayload(jsonString.toUtf8()); // 设置消息内容，注意转换
            message.setQos(1); // 设置服务质量等级
            // 使用MqttHandler实例发布消息
            quint16 messageId = GlobalVal::mqtt->publish(message);
            qDebug() << "Message published with ID" << messageId;
            ui->pushButtonCold->setStyleSheet("QPushButton { background-color: transparent; }");
        }
    }
    if(sender() == ui->pushButtonBuzzer)   //蜂鸣器
    {
        if(QString::number(fengmingqi.toInt())=="0")//打开
        {
            // 创建JSON对象
            QJsonObject jsonObject;
            // 添加控制指令类型
            jsonObject["type"] = QJsonValue(2);
            // 创建数据子对象
            QJsonObject dataObject;
            // 添加数据点唯一标识和数据点键值
            dataObject["key"] = QJsonValue(309);
            dataObject["val"] = QJsonValue("1");
            // 将数据子对象添加到主对象
            jsonObject["data"] = dataObject;
            // 创建QJsonDocument并添加JSON对象
            QJsonDocument jsonDoc(jsonObject);
            // 将JSON文档序列化为字符串
            QString jsonString = jsonDoc.toJson(QJsonDocument::Compact);
            // 创建一个QMQTT::Message对象
            QMQTT::Message message;
            message.setTopic("/app/data/down"); // 设置发布的主题
            message.setPayload(jsonString.toUtf8()); // 设置消息内容，注意转换
            message.setQos(1); // 设置服务质量等级
            // 使用MqttHandler实例发布消息
            quint16 messageId = GlobalVal::mqtt->publish(message);
            qDebug() << "Message published with ID" << messageId;
            ui->pushButtonBuzzer->setStyleSheet("QPushButton { background-color: green; }");
        }
        if(QString::number(fengmingqi.toInt())=="1")//关闭
        {
            // 创建JSON对象
            QJsonObject jsonObject;
            // 添加控制指令类型
            jsonObject["type"] = QJsonValue(2);
            // 创建数据子对象
            QJsonObject dataObject;
            // 添加数据点唯一标识和数据点键值
            dataObject["key"] = QJsonValue(309);
            dataObject["val"] = QJsonValue("0");
            // 将数据子对象添加到主对象
            jsonObject["data"] = dataObject;
            // 创建QJsonDocument并添加JSON对象
            QJsonDocument jsonDoc(jsonObject);
            // 将JSON文档序列化为字符串
            QString jsonString = jsonDoc.toJson(QJsonDocument::Compact);
            // 创建一个QMQTT::Message对象
            QMQTT::Message message;
            message.setTopic("/app/data/down"); // 设置发布的主题
            message.setPayload(jsonString.toUtf8()); // 设置消息内容，注意转换
            message.setQos(1); // 设置服务质量等级
            // 使用MqttHandler实例发布消息
            quint16 messageId = GlobalVal::mqtt->publish(message);
            qDebug() << "Message published with ID" << messageId;
            ui->pushButtonBuzzer->setStyleSheet("QPushButton { background-color: transparent; }");
        }
    }
    if(sender() == ui->pushButtonFan)    //风扇
    {
        if(QString::number(fengshan.toInt())=="0")
        {
            // 创建JSON对象
            QJsonObject jsonObject;
            // 添加控制指令类型
            jsonObject["type"] = QJsonValue(2);
            // 创建数据子对象
            QJsonObject dataObject;
            // 添加数据点唯一标识和数据点键值
            dataObject["key"] = QJsonValue(306);
            dataObject["val"] = QJsonValue("1");
            // 将数据子对象添加到主对象
            jsonObject["data"] = dataObject;
            // 创建QJsonDocument并添加JSON对象
            QJsonDocument jsonDoc(jsonObject);
            // 将JSON文档序列化为字符串
            QString jsonString = jsonDoc.toJson(QJsonDocument::Compact);
            // 创建一个QMQTT::Message对象
            QMQTT::Message message;
            message.setTopic("/app/data/down"); // 设置发布的主题
            message.setPayload(jsonString.toUtf8()); // 设置消息内容，注意转换
            message.setQos(1); // 设置服务质量等级
            // 使用MqttHandler实例发布消息
            quint16 messageId = GlobalVal::mqtt->publish(message);
            qDebug() << "Message published with ID" << messageId;
            // 播放电影
            movie->start();
        }
        if(QString::number(fengshan.toInt())=="1")
        {
            // 创建JSON对象
            QJsonObject jsonObject;
            // 添加控制指令类型
            jsonObject["type"] = QJsonValue(2);
            // 创建数据子对象
            QJsonObject dataObject;
            // 添加数据点唯一标识和数据点键值
            dataObject["key"] = QJsonValue(306);
            dataObject["val"] = QJsonValue("0");
            // 将数据子对象添加到主对象
            jsonObject["data"] = dataObject;
            // 创建QJsonDocument并添加JSON对象
            QJsonDocument jsonDoc(jsonObject);
            // 将JSON文档序列化为字符串
            QString jsonString = jsonDoc.toJson(QJsonDocument::Compact);
            // 创建一个QMQTT::Message对象
            QMQTT::Message message;
            message.setTopic("/app/data/down"); // 设置发布的主题
            message.setPayload(jsonString.toUtf8()); // 设置消息内容，注意转换
            message.setQos(1); // 设置服务质量等级
            // 使用MqttHandler实例发布消息
            quint16 messageId = GlobalVal::mqtt->publish(message);
            qDebug() << "Message published with ID" << messageId;
            // 停止播放播放电影
            movie->stop();
        }
    }
}

void DanStm32::dataUpSlot(QByteArray jsonData )//采集指令
{
    QString value (jsonData);
    QJsonParseError jsonError;
    QJsonDocument doc = QJsonDocument::fromJson(value.toUtf8() ,&jsonError);
    if (jsonError.error != QJsonParseError::NoError && !doc.isNull())
    {
        qDebug() << "Json格式错误！" << jsonError.error;
        return;
    }
    QJsonObject rootObj = doc.object();
    QJsonValue Stm32Value = rootObj.value("stm32");
    QJsonObject Stm32Obj = Stm32Value.toObject();
    QJsonValue dataValue =Stm32Obj.value("data");
    QJsonArray data = dataValue.toArray();
    for (int i = 0; i < data.count(); i++)
    {
        QJsonValue dataValueChild = data.at(i);
        QJsonObject dataObj = dataValueChild.toObject();
        QJsonValue keyValue = dataObj.value("key");
        if(keyValue.toInt()== 301)
        {
            QJsonValue varValue = dataObj.value("val");
            wendu=varValue;
            ui->lcdNumberTemperature->display(QString::number(varValue.toDouble()));//温度
        }
        else if(keyValue.toInt()==302)
        {
            QJsonValue varValue = dataObj.value("val");
            shidu=varValue;
            ui->lcdNumberHumidness->display(QString::number(varValue.toDouble()));//湿度
        }
        else if(keyValue.toInt()== 303)
        {
            QJsonValue varValue = dataObj.value("val");
            ui->lcdNumberLight->display(QString::number(varValue.toDouble()));//光照强度
        }
        else if(keyValue.toInt()== 304)
        {
            QJsonValue varValue = dataObj.value("val");//火焰检测
            QString huoyan=QString::number(varValue.toDouble());
            if (huoyan=="1")
            {
                ui->labelAlarm->setStyleSheet("QLabel { background-color: red; }");
            }
            else
            {
                ui->labelAlarm->setStyleSheet("QLabel { background-color: green; }");
            }
        }
        else if(keyValue.toInt()== 306)
        {
            QJsonValue varValue = dataObj.value("val");
            fengshan=varValue;//风扇状态
        }
        else if(keyValue.toInt()== 307)
        {
            QJsonValue varValue = dataObj.value("val");
            jiarepian=varValue;//加热片状态
        }
        else if(keyValue.toInt()== 308)
        {
            QJsonValue varValue = dataObj.value("val");
            zhilengpian=varValue;//制冷片状态
        }
        else if(keyValue.toInt()== 309)
        {
            QJsonValue varValue = dataObj.value("val");
            fengmingqi=varValue;//蜂鸣器状态
        }
        else if(keyValue.toInt()== 310)
        {
            QJsonValue varValue = dataObj.value("val");
            moshi=varValue;//模式
        }
    }
}

void DanStm32::setupRealtimeDataDemo(QCustomPlot *customPlot)//画图初始化
{
    customPlot->addGraph(); // blue line
    customPlot->graph(0)->setPen(QPen(Qt::blue));
    customPlot->graph(0)->setName("温度");
    customPlot->addGraph(); // red line
    customPlot->graph(1)->setPen(QPen(Qt::red));
    customPlot->graph(1)->setName("湿度");

    customPlot->xAxis->setTickLabelType(QCPAxis::ltDateTime);
    customPlot->xAxis->setDateTimeFormat("MM-dd hh:mm:ss");
    customPlot->xAxis->setAutoTickStep(false);
    customPlot->xAxis->setTickStep(2);
    customPlot->axisRect()->setupFullAxesBox();

    connect(&dataTimer, SIGNAL(timeout()), this, SLOT(realtimeDataSlot()));
    dataTimer.start(1000); // Interval 0 means to refresh as fast as possible
    customPlot->legend->setVisible(true);
}

void DanStm32::realtimeDataSlot()//动态曲线
{
    //key的单位是秒
    double key = QDateTime::currentDateTime().toMSecsSinceEpoch()/1000.0;
//    qsrand(QTime::currentTime().msec() + QTime::currentTime().second() * 10000);
    //使用随机数产生两条曲线
    //温度和适度可采集之后把实时的温湿度改上
    double value0 =wendu.toDouble();
    double value1 = shidu.toDouble();
    if (ui->checkBox_Temperature->isChecked())
        ui->customPlot->graph(0)->addData(key, value0);//添加数据1到曲线1
    if (ui->checkBox_Humidness->isChecked())
        ui->customPlot->graph(1)->addData(key, value1);//添加数据2到曲线2
    //删除8秒之前的数据。这里的8要和下面设置横坐标宽度的8配合起来
    //才能起到想要的效果，可以调整这两个值，观察显示的效果。
    ui->customPlot->graph(0)->removeDataBefore(key-8);
    ui->customPlot->graph(1)->removeDataBefore(key-8);

    //自动设定graph(1)曲线y轴的范围，如果不设定，有可能看不到图像
    //也可以用ui->customPlot->yAxis->setRange(up,low)手动设定y轴范围
    ui->customPlot->graph(0)->rescaleValueAxis();
    ui->customPlot->graph(1)->rescaleValueAxis(true);

    //这里的8，是指横坐标时间宽度为8秒，如果想要横坐标显示更多的时间
    //就把8调整为比较大到值，比如要显示60秒，那就改成60。
    //这时removeDataBefore(key-8)中的8也要改成60，否则曲线显示不完整。
    ui->customPlot->xAxis->setRange(key+0.25, 8, Qt::AlignRight);//设定x轴的范围
    ui->customPlot->replot();
}

void DanStm32::on_pushButtonShuaxin_clicked()//刷新内容
{
    // 创建JSON对象
    QJsonObject jsonObject;
    // 添加控制指令类型
    jsonObject["type"] = QJsonValue(1);
    // 创建QJsonDocument并添加JSON对象
    QJsonDocument jsonDoc(jsonObject);

    // 将JSON文档序列化为字符串
    QString jsonString = jsonDoc.toJson(QJsonDocument::Compact);

    // 创建一个QMQTT::Message对象
    QMQTT::Message message;
    message.setTopic("/app/data/down"); // 设置发布的主题
    message.setPayload(jsonString.toUtf8()); // 设置消息内容，注意转换
    message.setQos(1); // 设置服务质量等级

    // 使用MqttHandler实例发布消息
    quint16 messageId = GlobalVal::mqtt->publish(message);
    qDebug() << "Message published with ID" << messageId;
}

void DanStm32::on_pushButtonShoudong_clicked()//手动模式
{
    // 创建JSON对象
    QJsonObject jsonObject;
    // 添加控制指令类型
    jsonObject["type"] = QJsonValue(2);
    // 创建数据子对象
    QJsonObject dataObject;
    // 添加数据点唯一标识和数据点键值
    dataObject["key"] = QJsonValue(310);
    dataObject["val"] = QJsonValue("1");
    // 将数据子对象添加到主对象
    jsonObject["data"] = dataObject;
    // 创建QJsonDocument并添加JSON对象
    QJsonDocument jsonDoc(jsonObject);
    // 将JSON文档序列化为字符串
    QString jsonString = jsonDoc.toJson(QJsonDocument::Compact);
    // 创建一个QMQTT::Message对象
    QMQTT::Message message;
    message.setTopic("/app/data/down"); // 设置发布的主题
    message.setPayload(jsonString.toUtf8()); // 设置消息内容，注意转换
    message.setQos(1); // 设置服务质量等级
    // 使用MqttHandler实例发布消息
    quint16 messageId = GlobalVal::mqtt->publish(message);
    qDebug() << "Message published with ID" << messageId;
}

void DanStm32::on_pushButtonZidong_clicked()//自动模式
{
    // 创建JSON对象
    QJsonObject jsonObject;
    // 添加控制指令类型
    jsonObject["type"] = QJsonValue(2);
    // 创建数据子对象
    QJsonObject dataObject;
    // 添加数据点唯一标识和数据点键值
    dataObject["key"] = QJsonValue(310);
    dataObject["val"] = QJsonValue("0");
    // 将数据子对象添加到主对象
    jsonObject["data"] = dataObject;
    // 创建QJsonDocument并添加JSON对象
    QJsonDocument jsonDoc(jsonObject);
    // 将JSON文档序列化为字符串
    QString jsonString = jsonDoc.toJson(QJsonDocument::Compact);
    // 创建一个QMQTT::Message对象
    QMQTT::Message message;
    message.setTopic("/app/data/down"); // 设置发布的主题
    message.setPayload(jsonString.toUtf8()); // 设置消息内容，注意转换
    message.setQos(1); // 设置服务质量等级
    // 使用MqttHandler实例发布消息
    quint16 messageId = GlobalVal::mqtt->publish(message);
    qDebug() << "Message published with ID" << messageId;
}
